"""
fullout.py
"""


import sys
from time import time
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWebKitWidgets import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *

import logging                                                                  # запись логов
import re                                                                       # регулярные выражения
import sqlite3


sys.path.append('c:\PyLib')
from ConnSQL import *

word_del = ("ооо","ООО","ОАО","ИП","ЗАО","ПК") # абревиатуры


def org_norm(name):
    """
    Нормализация названий организаций.

    """
    name = ''.join(c for c in name if not (32 < ord(c) < 45)) # удалить запятие и двойные кавычки
    name = name.replace("-"," ")                                        # заменяем - на пробел
    name = name.split(' ')                                          # разбить название на слова
    name = [s for s in name if (not s in word_del) and (len(s) > 1)]                 # удалить из названий абревиатуры
    name.sort()
    return(','.join(name))# возвращаем сортированный список слов для поиска


def phone_norm(phones):
    """
    Нормализация телефонов.
    Сотовые до 10 цифр. 
    Самарские стационарные до 7 цифр.
    Тольяттинские стационарные до 6 цифр.
    """
    phones = ''.join(filter(lambda x: x.isalnum() or x == ',', phones))         # оставляем буквы, цыфры, запятые
    phones = phones.strip(',').split(',')                                       # убрать последнюю запятую и создать список

    for i, phone in enumerate(phones):
        p = phone.find('до')                                                    # убрать добавочный номер
        if p != -1:                                                             # всё после слов дополниельный или добавочный
            phone = phone[:p]
        if len(phone)>=11:                                                      # убрать код России - урезать до 10 цифр
            phone = phone[1:]
        if phone[:3]== '846':                                                   # убрать код Самары
            phone = phone[3:]
        if phone[:4]== '8482':                                                  # убрать код Тольятти
            phone = phone[3:]
        phones[i] = phone
    phones.sort()                                                      
    return(','.join(phones))# возвращаем сортированный список телефонов



    
def btn_clear_click():
    """
    Нормализация телефонов и названий организаций.
    Удаление дублей по названию.
    Удаление дублей по телефонам.
    """
    
    conn = sqlite3.connect("distrib.db")                                        # все вакансии для распределения

    select = conn.cursor()                                                      # для обхода записей
    update = conn.cursor()                                                      # для обновления записей
    
    update.execute("DELETE FROM vacant WHERE (org = '') OR (phone = '');")                                 # удалить пустые организации и телефоны
    conn.commit()

    select.execute("SELECT ROWID, org, phone FROM vacant;")                     # все записи
    
    for rowid, org, phone in select:
        org_find = org_norm(org) # нормализация организации
        phone_find = phone_norm(phone)                                     # нормализация телефонов
    
        sql = ("UPDATE vacant SET org_find = ?, phone_find = ? "
               "WHERE ROWID = {}".format(rowid))
        try:                                                                    # обработка исключения
            update.execute(sql,(org_find, phone_find))        # Выполняем SQL-запрос
        except sqlite3.Error as e:
            logging.error('btn_find_name: {} {}'.format( e.args[0],sql))
            quit()
        else:
            conn.commit()
#
    update.execute("DELETE FROM vacant WHERE ROWID NOT IN ("                     # удалить дубли по имени организации
        "SELECT MIN(ROWID) FROM vacant GROUP BY org_find);")
    conn.commit()
    update.execute("DELETE FROM vacant WHERE ROWID NOT IN ("                     # удалить дубли по телефонам
        "SELECT MIN(ROWID) FROM vacant GROUP BY phone_find);")
    conn.commit()

    conn.close()
    
    
def btn_find_click():
    """
    Подготовка рабочей таблицы. Перенос информации в рабочую таблицу.
    Удаление повторяющихся организаций. Нормализация телефонов.
    Удаление организаций с повторяющимися телефонами.
    """

    select = conn.cursor()                                                      # для обхода записей
    update = conn.cursor()                                                      # для обновления записей
    lexema = QSqlQuery(dbMS)

    select.execute("SELECT ROWID, org_find, org_crm, phone_find, curator FROM vacant;")                     # читать телефоны

    for rowid, org_find, org_crm, phone_find, curator in select:
        # print(rowid, org_find, org_crm, phone_find, curator)
        phones = phone_find.split(',')  # список телефонов
        condition = []
        for phone in phones:                                        # формирование условия LIKE
            condition.append("Phone LIKE '%{}%'".format(phone))
        condition = ' OR '.join(condition)
        sql = ("SELECT s.fullname, u.name FROM dbo.Spr_Org s "              # запрос на поиск в телефонам
               "INNER JOIN dbo.Unianalit u ON u.vcode = s.kurator WHERE {}"
               .format(condition))
        lexema.exec(sql)
        if lexema.next():                                                   # первая попавшаяся запись
            curator = re.match('[^ ]*',lexema.value(1)).group()             # отбросить имя и отчество куратора
            org_crm = "({}){}".format(curator, lexema.value(0).rstrip())    # название организации в лексеме
        """ Отключено по просьбе Лёушкина."""
        # if not curator:                                                         # куратор не найден
            # names = org_find.split(',')  # слова для поиска по имени
            # condition = []
            # for name in names:                                        # формирование условия LIKE
                # condition.append("u.name LIKE '%{}%'".format(name))
            # condition = ' AND '.join(condition)

            # sql = ("SELECT s.fullname, u.name FROM dbo.Spr_Org s INNER JOIN " 
                   # "dbo.Unianalit u ON u.vcode=s.kurator WHERE s.fullname in "
                   # "(select s.fullname from dbo.spr_org s "                              # запрос на поиск в названию
                   # " inner join dbo.unianalit u on u.vcode=s.code where {})"
                   # .format(condition))
            # logging.debug('поиск организации|{}|'.format(sql))
            # lexema.exec(sql)
            # lexema.last();                                                      # количество записей
            # numRows = lexema.at() + 1;
            # logging.debug('найдено|{}|'.format(sql))
            # if numRows == 1:                                                    # одна запись - точный поиск
                # curator = re.match('[^ ]*',lexema.value(1)).group()             # отбросить имя и отчество куратора
                # org_crm = "({}){}".format(curator, lexema.value(0).rstrip())    # название организации в лексеме
            # if numRows > 1:                                                     # не точный поиск
                # org_crm = "Найдено: {} организаций".format(numRows)

        sql = ("UPDATE vacant SET org_crm = ?, curator = ? "
               "WHERE ROWID = {}".format(rowid))
        try:                                                                    # обработка исключения
            update.execute(sql,(org_crm, curator))        # Выполняем SQL-запрос
        except sqlite3.Error as e:
            logging.error('btn_find_name: {} {}'.format( e.args[0],sql))
            quit()
        else:
            conn.commit()

    btn_find.setEnabled(False)


def main():
    
    app = QApplication(sys.argv)

    logging.basicConfig(filename='log.txt',level=logging.DEBUG)

    dbMS = QSqlDatabase.addDatabase("QODBC")                                    # соедиение с лексемой
    dbMS.setDatabaseName("lexema")
    dbMS.setUserName("sa")
    dbMS.setPassword("5318")
    if dbMS.open():
        print("соединение lexema")

    window = QWidget()
    window.setWindowTitle("CRM")
    window.resize(200, 200)

    vbox_btn = QVBoxLayout()                                                    # вертикальный контейнер кнопок
        # КНОПКИ
    btn_clear = QPushButton("Очистка")
    btn_clear.clicked.connect(btn_clear_click)
    vbox_btn.addWidget(btn_clear)

    btn_find = QPushButton("Поиск по CRM")
    btn_find.clicked.connect(btn_find_click)
    vbox_btn.addWidget(btn_find)

    btnQuit = QPushButton("ВЫХОД")
    vbox_btn.addWidget(btnQuit)
    btnQuit.clicked.connect(quit)
    
    vbox_btn.addStretch()                                                       # добавляем пустое простанство за кнопками

    window.setLayout(vbox_btn)
    window.show()

    btn_clear_click()
    btn_find_click()
    
    """ Меняем всех пустых кураторов на Супервайзера."""
    query.execute("UPDATE vacant SET curator = 'Супервайзер' WHERE curator = ''")
    conn.commit()

    """Собираем всех кураторов из базы и делаем из них список."""
    query.execute("SELECT curator FROM vacant GROUP BY curator;")
    curators = list(query)
    
    t = datetime.datetime.today()
    pref = t.strftime("%d-%I-%M")

    # Итерация спискау кураторов.
    # вывод csv по каждому менеджеру
    for cur in curators:                                                        # вывод csv по каждому менеджеру
        curator = cur[0]
        namef = "outfile\\{} {}.csv".format(pref, curator)
        f = open(namef, 'w')
        query.execute("SELECT org, face, phone, phone_find, org_CRM,"
            "url, curator "
            "FROM vacant WHERE curator = '{}'".format(curator))
        for org, face, phone, phone_find, org_CRM, url, curator in query:
            s = ('{}${}${}$>{}<${}$=HYPERLINK("{}")${}\n'.
            format(org, face, phone, phone_find, org_CRM, url, curator))
            f.write(s)
        f.close()

    
    sys.exit(app.exec_())

    dbMy.close()
    QSqlDatabase.removeDatabase("My")

if __name__ == '__main__':                                                      

    main()